//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2011 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef _BUOLA_ALGORITHM_TRIM_H_
#define _BUOLA_ALGORITHM_TRIM_H_

#include <buola/functors/predicates/char.h>
#include <buola/algorithm/container.h>

namespace buola {

///\addtogroup algorithm
///@{

///\name Trim
//@{

///removed the leading elements of \p pCont for which \p pPred returns true

///If \p pPred is not specified, leading whitespace is removed.
template<typename tCont,typename tPred=fn::AIsAsciiSpace>
void trim_left(tCont &pCont,const tPred &pPred=fn::is_ascii_space())
{
    auto lI=pCont.begin();
    auto lE=pCont.end();
    if(lI==lE||!pPred(*lI)) return;
    
    for(++lI;lI!=lE&&pPred(*lI);++lI) {}

    pCont.erase(pCont.begin(),lI);
}

///removed the trailing elements of \p pCont for which \p pPred returns true

///If \p pPred is not specified, trailing whitespace is removed.
template<typename tCont,typename tPred=fn::AIsAsciiSpace>
void trim_right(tCont &pCont,const tPred &pPred=fn::is_ascii_space())
{
    auto lI=pCont.end();
    auto lB=pCont.begin();
    if(lI==lB) return;
    if(!pPred(*--lI)) return;
    
    while(lI!=lB)
    {
        if(!pPred(*--lI))
        {
            ++lI;
            break;
        }
    }

    pCont.erase(lI,pCont.end());
}

///removed the leading and trailing elements of \p pCont for which \p pPred returns true

///If \p pPred is not specified, leading and trailing whitespace is removed.
///
///It is equivalent to a call to \ref trim_right followed by a call to \ref trim_left.
template<typename tCont,typename tPred=fn::AIsAsciiSpace>
inline void trim(tCont &pCont,const tPred &pPred=fn::is_ascii_space())
{
    trim_right(pCont,pPred);
    trim_left(pCont,pPred);
}

//@}

///@}

/*namespace buola*/ }

#endif
